/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = amqp_content.c                                     */
/*  NOTE      =                                                    */
/*  DATE      = 2015/09/09 by geyh                                 */
/*******************************************************************/
#include <stdio.h>
#include <stdlib.h>

#include "frbyte_buffer.h"
#include "frcomm.h"
#include "frmem.h"
#include "frct_comm.h"
#include "frreport_comm.h"

#include "amqp_content.h"

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};

union int32_float_bits {
    int32_t int_bits;
    float float_bits;
};


/*******************************************************************************
*  FUNC     :  amqp 跳过不需要的内容
*  ARGS     :  p_st_data                    输入数据信息
*           :
*  RTN      :  FR_FAIL                      失败
*           :  FR_SUCC                      成功
*  NOTE     :
*******************************************************************************/
int amqp_skip_content(Frbyte_Packet *p_st_data, int *p_ui_skip_len)
{
    int i_ret = 0;
    unsigned  short s_data_type = 0x00;
    unsigned int ui_tmp_size = 0;

    if(p_st_data == NULL || p_ui_skip_len == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_short(p_st_data, 1, (uint16_t *)&s_data_type, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(s_data_type)
    {
        case 0x40:
        case 0x41:
        case 0x42:
        case 0x43:
        case 0x44:
        case 0x45:
            i_ret = FR_SUCC;
            *p_ui_skip_len = 1;
            break;

            //ubyte
        case 0x50:
            i_ret = bytebuff_skip(p_st_data, 1);
            *p_ui_skip_len = 2;
            break;

            //byte
        case 0x51:
            i_ret = bytebuff_skip(p_st_data, 1);
            *p_ui_skip_len = 2;
            break;

        case 0x52:
        case 0x53:
        case 0x54:
        case 0x55:
            i_ret = bytebuff_skip(p_st_data, 1);
            *p_ui_skip_len = 2;
            break;

            //boolean
        case 0x56:
            i_ret = bytebuff_skip(p_st_data, 1);
            *p_ui_skip_len = 2;
            break;

            //ushort
        case 0x60:
            i_ret = bytebuff_skip(p_st_data, 2);
            *p_ui_skip_len = 3;
            break;

            //short
        case 0x61:
            i_ret = bytebuff_skip(p_st_data, 2);
            *p_ui_skip_len = 3;
            break;

            //uint
        case 0x70:
            i_ret = bytebuff_skip(p_st_data, 4);
            *p_ui_skip_len = 5;
            break;

            //int
        case 0x71:
            i_ret = bytebuff_skip(p_st_data, 4);
            *p_ui_skip_len = 5;
            break;

            //float
        case 0x72:
            i_ret = bytebuff_skip(p_st_data, 4);
            *p_ui_skip_len = 5;
            break;

            //UTF-32BE encoded Unicode character
        case 0x73:
            i_ret = bytebuff_skip(p_st_data, 4);
            *p_ui_skip_len = 5;
            break;

            //decimal32
        case 0x74:
            i_ret = bytebuff_skip(p_st_data, 4);
            *p_ui_skip_len = 5;
            break;

            //ulong
        case 0x80:
            i_ret = bytebuff_skip(p_st_data, 8);
            *p_ui_skip_len = 9;
            break;

            //long
        case 0x81:
            i_ret = bytebuff_skip(p_st_data, 8);
            *p_ui_skip_len = 9;
            break;

            //double
        case 0x82:
            i_ret = bytebuff_skip(p_st_data, 8);
            *p_ui_skip_len = 9;
            break;

            //decimal64
        case 0x84:
            i_ret = bytebuff_skip(p_st_data, 8);
            *p_ui_skip_len = 9;
            break;

            //decimal128
        case 0x94:
            i_ret = bytebuff_skip(p_st_data, 16);
            *p_ui_skip_len = 17;
            break;

            //timestamp
        case 0x83:
            i_ret = bytebuff_skip(p_st_data, 8);
            *p_ui_skip_len = 9;
            break;

            //uuid
        case 0x98:
            i_ret = bytebuff_skip(p_st_data, 16);
            *p_ui_skip_len = 17;
            break;

            // 2^8 - 1 octets of binary data
        case 0xa0:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 2;
            break;

            //2^32 - 1 octets of binary data
        case 0xb0:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 5;
            break;


            // 2^8 - 1 octets of UTF-8 Unicode data
        case 0xa1:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 2;
            break;

            //2^32 - 1 octets of UTF-8 Unicode data
        case 0xb1:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 5;
            break;

            //symbol
        case 0xa3:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 2;
            break;

        case 0xb3:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 5;
            break;

            //list 8
        case 0xc0:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 2;
            break;

            //list 32
        case 0xd0:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 5;
            break;

            //map 8
        case 0xc1:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 2;
            break;

            //map 32:
        case 0xd1:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            *p_ui_skip_len = ui_tmp_size + 5;
            break;

        default:
            return FR_FAIL;
    }

    return i_ret;

}


/*******************************************************************************
*  FUNC     :  amqp 跳过不需要的内容
*  ARGS     :  p_st_data                    输入数据信息
*           :
*  RTN      :  FR_FAIL                      失败
*           :  FR_SUCC                      成功
*  NOTE     :
*******************************************************************************/
int amqp_get_content(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, const char *p_field_name , int i_use_request)
{
    int i_ret = 0;
    unsigned short us_data_type = 0;
    unsigned int ui_tmp_size = 0;
    int i_count = 0;

    //string
    char *p_field_value = NULL;
    union int64_double_bits u_64bits;
    uint64_t u64_len = 0;
    double db_value = 0.0;
    union int32_float_bits u_32bits;
    uint32_t u32_len = 0;
    float fl_value = 0.0;
    long long ll_value = 0;
    int i_value = 0;

    if(p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_short(p_st_data, 1, (uint16_t *)&us_data_type, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(us_data_type)
    {
        //null
        case 0x40:
            i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, "\0");
            return i_ret;

            //true
        case 0x41:
            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, 1);
            return i_ret;

            //false
        case 0x42:
            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, 0);
            return i_ret;

            //uint 0
        case 0x43:
            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, 0);
            return i_ret;

            //ulong
        case 0x44:
            i_ret = frreport_body_l7_add_long(p_st_body_data, p_field_name, 0);
            return i_ret;

            //list 0
        case 0x45:
            i_ret = FR_SUCC;
            break;
            //boolean
        case 0x56:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_value);
            return i_ret;

            //ubyte
        case 0x50:
        case 0x51:
        case 0x52:
        case 0x53:
        case 0x54:
        case 0x55:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_value);
            return i_ret;

            //ushort
        case 0x60:
            i_ret = bytebuff_get_int(p_st_data, 2, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_value);
            return i_ret;

            //short
        case 0x61:
            i_ret = bytebuff_get_int(p_st_data, 2, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_value);
            return i_ret;

            //uint
        case 0x70:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_value);
            return i_ret;

            //int
        case 0x71:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_value);
            return i_ret;

            //ulong
        case 0x80:
            i_ret = bytebuff_get_long(p_st_data, 8, (uint64_t *)&ll_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_long(p_st_body_data, p_field_name, ll_value);
            return i_ret;

            //long
        case 0x81:
            i_ret = bytebuff_get_long(p_st_data, 8, (uint64_t *)&ll_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_long(p_st_body_data, p_field_name, ll_value);
            return i_ret;

            //float
        case 0x72:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            u_32bits.int_bits = u32_len;
            fl_value = u_32bits.float_bits;

            i_ret = frreport_body_l7_add_float(p_st_body_data, p_field_name, fl_value);
            return i_ret;

            //double
        case 0x82:
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            u_64bits.int_bits = u64_len;
            db_value = u_64bits.double_bits;

            i_ret = frreport_body_l7_add_double(p_st_body_data, p_field_name, db_value);
            return i_ret;

            //decimal32
        case 0x74:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            u_32bits.int_bits = u32_len;
            fl_value = u_32bits.float_bits;

            i_ret = frreport_body_l7_add_float(p_st_body_data, p_field_name, fl_value);
            return i_ret;

            //decimal64
        case 0x84:
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            u_64bits.int_bits = u64_len;
            db_value = u_64bits.double_bits;

            i_ret = frreport_body_l7_add_double(p_st_body_data, p_field_name, db_value);
            return i_ret;

            //decimal128 todo
        case 0x94:
            i_ret = bytebuff_skip(p_st_data, 16);
            break;

            //UTF-32BE encoded Unicode character
        case 0x73:
            i_ret = bytebuff_skip(p_st_data, 4);
            break;

            //timestamp
        case 0x83:
            i_ret = bytebuff_get_long(p_st_data, 8, (uint64_t *)&ll_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = frreport_body_l7_add_long(p_st_body_data, p_field_name, ll_value);
            return i_ret;

            //uuid
        case 0x98:
            p_field_value = (char *)frmalloc(16 + 1);
            if(p_field_value == NULL)
                return FR_FAIL;

            i_ret = bytebuff_get_bytes(p_st_data, p_field_value, 16);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            p_field_value[16] = '\0';

            i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
            frfree(p_field_value);
            return i_ret;

            // 2^8 - 1 octets of binary data
        case 0xa0:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

//            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
//            if(i_ret == FR_FAIL)
//                return FR_FAIL;

            if(p_field_name == NULL)
            {
                if(i_use_request)
                {
                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.method", "PUT");
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.message.type", "binary");
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    p_field_value = (char *)frmalloc(ui_tmp_size);
                    if(p_field_value == NULL)
                        return FR_FAIL;

                    i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_bin(p_st_body_data, "request.mq.message.binary", p_field_value, ui_tmp_size);
                    frfree(p_field_value);

                }
                else
                {
                    i_ret = frreport_body_l7_add_int(p_st_body_data, "notify.mq.message.size", 1);
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.message.type.1", "binary");
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    p_field_value = (char *)frmalloc(ui_tmp_size);
                    if(p_field_value == NULL)
                        return FR_FAIL;

                    i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_bin(p_st_body_data, "notify.mq.message.binary.1", p_field_value, ui_tmp_size);
                    frfree(p_field_value);
                }
            }
            else
            {
                p_field_value = (char *)frmalloc(ui_tmp_size);
                if(p_field_value == NULL)
                    return FR_FAIL;

                i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                if(i_ret == FR_FAIL)
                {
                    frfree(p_field_value);
                    return FR_FAIL;
                }

                i_ret = frreport_body_l7_add_bin(p_st_body_data, p_field_name, p_field_value, ui_tmp_size);
                frfree(p_field_value);
            }

            return i_ret;

            //2^32 - 1 octets of binary data
        case 0xb0:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
//            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
//            if(i_ret == FR_FAIL)
//                return FR_FAIL;

            if(p_field_name == NULL)
            {
                if(i_use_request)
                {
                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.method", "PUT");
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.message.type", "binary");
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    p_field_value = (char *)frmalloc(ui_tmp_size);
                    if(p_field_value == NULL)
                        return FR_FAIL;

                    i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_bin(p_st_body_data, "request.mq.message.binary", p_field_value, ui_tmp_size);
                    frfree(p_field_value);

                }
                else
                {
                    i_ret = frreport_body_l7_add_int(p_st_body_data, "notify.mq.message.size", 1);
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.message.type.1", "binary");
                    if(i_ret == FR_FAIL)
                        return FR_FAIL;

                    p_field_value = (char *)frmalloc(ui_tmp_size);
                    if(p_field_value == NULL)
                        return FR_FAIL;

                    i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_bin(p_st_body_data, "notify.mq.message.binary.1", p_field_value, ui_tmp_size);
                    frfree(p_field_value);
                }
            }
            else
            {
                p_field_value = (char *)frmalloc(ui_tmp_size);
                if(p_field_value == NULL)
                    return FR_FAIL;

                i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                if(i_ret == FR_FAIL)
                {
                    frfree(p_field_value);
                    return FR_FAIL;
                }

                i_ret = frreport_body_l7_add_bin(p_st_body_data, p_field_name, p_field_value, ui_tmp_size);
                frfree(p_field_value);
            }

            return i_ret;

            // 2^8 - 1 octets of UTF-8 Unicode data
        case 0xa1:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            if(i_use_request)
            {
                p_field_value = (char *)frmalloc(ui_tmp_size + 1);
                if(p_field_value == NULL)
                    return FR_FAIL;

                i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
                p_field_value[ui_tmp_size] = '\0';

                if(p_field_name)
                    i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
                else
                {
                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.method", "PUT");
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.message.type", "text");
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.message.text", p_field_value);
                }
                frfree(p_field_value);
            }
            else
            {
                p_field_value = (char *)frmalloc(ui_tmp_size + 1);
                if(p_field_value == NULL)
                    return FR_FAIL;

                i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
                p_field_value[ui_tmp_size] = '\0';

                if(p_field_name)
                    i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
                else
                {
                    i_ret = frreport_body_l7_add_int(p_st_body_data, "notify.mq.message.size", 1);
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.message.type.1", "text");
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }
                    i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.message.text.1", p_field_value);
                }

                frfree(p_field_value);
            }

            return i_ret;

            //2^32 - 1 octets of UTF-8 Unicode data
        case 0xb1:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            if(i_use_request)
            {
                p_field_value = (char *)frmalloc(ui_tmp_size + 1);
                if(p_field_value == NULL)
                    return FR_FAIL;

                i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
                p_field_value[ui_tmp_size] = '\0';

                if(p_field_name)
                    i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
                else
                {
                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.method", "PUT");
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.message.type", "text");
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.message.text", p_field_value);
                }
                frfree(p_field_value);
            }
            else
            {
                p_field_value = (char *)frmalloc(ui_tmp_size + 1);
                if(p_field_value == NULL)
                    return FR_FAIL;

                i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
                p_field_value[ui_tmp_size] = '\0';

                if(p_field_name)
                    i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
                else
                {
                    i_ret = frreport_body_l7_add_int(p_st_body_data, "notify.mq.message.size", 1);
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }

                    i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.message.type.1", "text");
                    if(i_ret == FR_FAIL)
                    {
                        frfree(p_field_value);
                        return FR_FAIL;
                    }
                    i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.message.text.1", p_field_value);
                }

                frfree(p_field_value);
            }

            return i_ret;

            //symbol
        case 0xa3:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
//            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
//            if(i_ret == FR_FAIL)
//                return FR_FAIL;

            p_field_value = (char *)frmalloc(ui_tmp_size);
            if(p_field_value == NULL)
                return FR_FAIL;

            i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
            if(i_ret == FR_FAIL)
            {
                frfree(p_field_value);
                return FR_FAIL;
            }

            i_ret = frreport_body_l7_add_bin(p_st_body_data, p_field_name, p_field_value, ui_tmp_size);
            frfree(p_field_value);
            return i_ret;

        case 0xb3:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
//            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
//            if(i_ret == FR_FAIL)
//                return FR_FAIL;
            p_field_value = (char *)frmalloc(ui_tmp_size);
            if(p_field_value == NULL)
                return FR_FAIL;

            i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_tmp_size);
            if(i_ret == FR_FAIL)
            {
                frfree(p_field_value);
                return FR_FAIL;
            }

            i_ret = frreport_body_l7_add_bin(p_st_body_data, p_field_name, p_field_value, ui_tmp_size);
            frfree(p_field_value);
            return i_ret;

            //list 8 todo
        case 0xc0:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            break;

            //list 32
        case 0xd0:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            i_ret = bytebuff_skip(p_st_data, ui_tmp_size);
            break;

            //map 8
        case 0xc1:
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_count, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = amqp_map_message_parse(p_st_data, p_st_body_data, i_count, i_use_request);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            break;

            //map 32:
        case 0xd1:
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_tmp_size, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_count, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_ret = amqp_map_message_parse(p_st_data, p_st_body_data, i_count, i_use_request);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            break;

        default:
            return FR_FAIL;
    }

    return i_ret;

}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  i_flag_need                  FR_YES  获取数据   FR_NO    跳过数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_short_string(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, const char *p_field_name, int i_flag_need)
{
    int i_ret = 0;
    int i_data_len = 0;
    char *p_field_value = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_data_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(i_flag_need == FR_NO)
    {
        i_ret = bytebuff_skip(p_st_data, i_data_len);
        return i_ret;
    }
    else
    {
        p_field_value = (char *)frmalloc(i_data_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_field_value, i_data_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }
        p_field_value[i_data_len] = '\0';

        i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
        frfree(p_field_value);
        return i_ret;

    }

}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  i_flag_need                  FR_YES  获取数据   FR_NO    跳过数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_long_string(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, const char *p_field_name, int i_flag_need)
{
    int i_ret = 0;
    int i_data_len = 0;
    char *p_field_value = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_data_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(i_flag_need == FR_NO)
    {
        i_ret = bytebuff_skip(p_st_data, i_data_len);
        return i_ret;
    }
    else
    {
        p_field_value = (char *)frmalloc(i_data_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_field_value, i_data_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }
        p_field_value[i_data_len] = '\0';

        i_ret = frreport_body_l7_add_str_limit(p_st_body_data, p_field_name, p_field_value, APM_REPORT_MQ_MAX);
        frfree(p_field_value);
        return i_ret;

    }

}

int amqp_add_string(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, const char *p_field_name, int i_flag_need)
{
    int i_ret = 0;
    char c_type;

    if(p_st_data == NULL || p_st_body_data == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(c_type == '\xa1')
        i_ret = amqp_add_short_string(p_st_data, p_st_body_data, p_field_name, i_flag_need);
    else if(c_type == '\xb1')
        i_ret = amqp_add_long_string(p_st_data, p_st_body_data, p_field_name, i_flag_need);
    else
        return FR_FAIL;

    return i_ret;

}

/*******************************************************************************
*  FUNC     :  取得字符串内容
*  ARGS     :  p_st_data                    输入数据信息
*           :  pp_field_value               取得的字段值
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_get_string(Frbyte_Packet *p_st_data, char **pp_field_value, int *p_ui_skip_len)
{
    int i_ret = 0;
    char *p_field_value = NULL;
    unsigned int ui_value_len = 0;
    char c_type;

    if(p_st_data == NULL || pp_field_value == NULL || p_ui_skip_len == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(c_type)
    {
        case '\x40':
            ui_value_len = 0;
            *p_ui_skip_len = 1;
            break;

        case '\xa1':
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_value_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = ui_value_len + 2;
            break;

        case '\xb1':
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_value_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = ui_value_len + 5;
            break;

        default:
            return FR_FAIL;

    }

    if(ui_value_len == 0)
    {
        p_field_value = frstrdup("\0");
        if(p_field_value == NULL)
            return FR_FAIL;
    }
    else
    {
        p_field_value = (char *)frmalloc(ui_value_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_value_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }

        p_field_value[ui_value_len] = '\0';
    }

    *pp_field_value = p_field_value;
    return FR_SUCC;

}


/*******************************************************************************
*  FUNC     :  取得数值
*  ARGS     :  p_st_data                    输入数据信息
*           :  pp_field_value               取得的字段值
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_get_int(Frbyte_Packet *p_st_data, int *p_i_value, int *p_ui_skip_len)
{
    int i_ret = 0;
    int i_value = 0;
    char c_type;

    if(p_st_data == NULL || p_i_value == NULL || p_ui_skip_len == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(c_type)
    {
        case '\x43':
            i_value = 0;
            *p_ui_skip_len = 1;
            break;

        case '\x52':
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = 2;
            break;

        case '\x70':
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = 5;
            break;

        default:
            return FR_FAIL;

    }

    *p_i_value = i_value;
    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  取得字符串内容
*  ARGS     :  p_st_data                    输入数据信息
*           :  pp_field_value               取得的字段值
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_get_binary(Frbyte_Packet *p_st_data, char **pp_field_value, int *p_ui_skip_len)
{
    int i_ret = 0;
    char *p_field_value = NULL;
    unsigned int ui_value_len = 0;
    char c_type;

    if(p_st_data == NULL || pp_field_value == NULL || p_ui_skip_len == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(c_type)
    {
        case '\x40':
            ui_value_len = 0;
            *p_ui_skip_len = 1;
            break;

        case '\xa0':
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_value_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = ui_value_len + 2;
            break;

        case '\xb0':
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_value_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = ui_value_len + 5;
            break;

        default:
            return FR_FAIL;

    }

    if(ui_value_len == 0)
    {
        p_field_value = frstrdup("\0");
        if(p_field_value == NULL)
            return FR_FAIL;
    }
    else
    {
        p_field_value = (char *)frmalloc(ui_value_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_value_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }

        p_field_value[ui_value_len] = '\0';
    }

    *pp_field_value = p_field_value;
    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  取得字符串内容
*  ARGS     :  p_st_data                    输入数据信息
*           :  pp_field_value               取得的字段值
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_get_symbol(Frbyte_Packet *p_st_data, char **pp_field_value, int *p_ui_skip_len)
{
    int i_ret = 0;
    char *p_field_value = NULL;
    unsigned int ui_value_len = 0;
    char c_type;

    if(p_st_data == NULL || pp_field_value == NULL || p_ui_skip_len == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(c_type)
    {
        case '\x40':
            ui_value_len = 0;
            *p_ui_skip_len = 1;
            break;

        case '\xa3':
            i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&ui_value_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = ui_value_len + 2;
            break;

        case '\xb3':
            i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_value_len, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_ui_skip_len = ui_value_len + 5;
            break;

        default:
            return FR_FAIL;

    }

    if(ui_value_len == 0)
    {
        p_field_value = frstrdup("\0");
        if(p_field_value == NULL)
            return FR_FAIL;
    }
    else
    {
        p_field_value = (char *)frmalloc(ui_value_len + 1);
        if(p_field_value == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_field_value, ui_value_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_field_value);
            return FR_FAIL;
        }

        p_field_value[ui_value_len] = '\0';
    }

    *pp_field_value = p_field_value;
    return FR_SUCC;

}

//uint  1bit
/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_uint(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int *p_ui_skip_len, const char *p_field_name)
{
    int i_ret = 0, i_mess_format = 0;
    char c_type;

    if(p_st_data == NULL || p_st_body_data == NULL || p_ui_skip_len == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(c_type == '\x43')
    {
        *p_ui_skip_len = 1;
        return FR_SUCC;
    }
    else if(c_type == '\x52')
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_mess_format, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        *p_ui_skip_len = 2;
    }
    else if(c_type == '\x70')
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_mess_format, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        *p_ui_skip_len = 5;
    }

    i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_mess_format);
    return i_ret;

}

//uint  1bit
/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_ubyte(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int *p_ui_skip_len, const char *p_field_name)
{
    int i_ret = 0, i_field_value = 0;
    char c_type;

    if(p_st_data == NULL || p_st_body_data == NULL || p_ui_skip_len == NULL || p_field_name == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(c_type != '\x50')
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_field_value, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = frreport_body_l7_add_int(p_st_body_data, p_field_name, i_field_value);
    *p_ui_skip_len = 2;
    return i_ret;

}


//trans  arguments
/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_arguments(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, st_amqp_private_data *p_st_private)
{
    int i_ret = 0;
    char c_type;
    int i_tmp_len = 0, i_skip_len = 0;


    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //arguments  list
    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    if(c_type == '\xc0')
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\xd0')
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\x45')
    {
        i_tmp_len = 0;
    }
    else
    {
        return FR_FAIL;
    }

    if(i_tmp_len)
    {
        i_ret = bytebuff_skip(p_st_data, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        //handle
        i_ret = amqp_skip_content(p_st_data, &i_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len -= i_skip_len;

        //deliveryId
        if(p_st_private->i_refence == 0)
        {
            i_ret = amqp_get_int(p_st_data, &p_st_private->i_id_first, &i_skip_len);
            p_st_private->i_id_last = p_st_private->i_id_first;
        }
        else
            i_ret = amqp_get_int(p_st_data, &p_st_private->i_id_last, &i_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len -= i_skip_len;

        //deliveryTag
        i_ret = amqp_skip_content(p_st_data, &i_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len -= i_skip_len;

        if(i_tmp_len < 0)
            return FR_FAIL;

        //后去  mess_format  类型
        i_ret = amqp_add_uint(p_st_data, p_st_body_data, &i_skip_len, "mess_format");
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_tmp_len -= i_skip_len;
        if(i_tmp_len < 0)
            return FR_FAIL;

        //跳过该链表剩余项
        i_ret = bytebuff_skip(p_st_data, i_tmp_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_mess_header(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, st_amqp_private_data *p_st_private)
{
    int i_ret = 0;
    char c_type;
    int i_tmp_len = 0, ui_skip_len = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //mess header  list
    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    if(c_type == '\xc0')
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\xd0')
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\x45')
    {
        i_tmp_len = 0;
    }
    else
    {
        return FR_FAIL;
    }

    if(i_tmp_len)
    {
        i_ret = bytebuff_skip(p_st_data, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len-=1;

        //durable
        i_ret = amqp_skip_content(p_st_data, &ui_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_tmp_len -= ui_skip_len;
        if(i_tmp_len < 0)
            return FR_FAIL;

        //后去  mess_priority  类型
        if(p_st_private->is_topic)
        {
            if(p_st_private->i_use_request)
                i_ret = amqp_add_ubyte(p_st_data, p_st_body_data, &ui_skip_len, "publish.mq.priority");
            else
                i_ret = amqp_add_ubyte(p_st_data, p_st_body_data, &ui_skip_len, "notify.mq.priority");
        }
        else
        {
            if(p_st_private->i_use_request)
                i_ret = amqp_add_ubyte(p_st_data, p_st_body_data, &ui_skip_len, "request.mq.priority");
            else
                i_ret = amqp_add_ubyte(p_st_data, p_st_body_data, &ui_skip_len, "response.mq.priority");
        }
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_tmp_len -= ui_skip_len;
        if(i_tmp_len < 0)
            return FR_FAIL;

        //跳过该链表剩余项
        i_ret = bytebuff_skip(p_st_data, i_tmp_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

    }

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_mess_properties(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, st_amqp_private_data *p_st_private)
{
    int i_ret = 0, i_index = 0;
    char c_type;
    int i_tmp_len = 0, ui_skip_len = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //mess header  list
    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    if(c_type == '\xc0')
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\xd0')
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\x45')
    {
        i_tmp_len = 0;
    }
    else
    {
        return FR_FAIL;
    }

    if(i_tmp_len)
    {
        i_ret = bytebuff_skip(p_st_data, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        for(i_index = 0; i_index < 2; i_index++)
        {
            i_ret = amqp_skip_content(p_st_data, &ui_skip_len);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_tmp_len -= ui_skip_len;
            if(i_tmp_len < 0)
                return FR_FAIL;
        }

        // queue
        i_ret = amqp_get_string(p_st_data, &p_st_private->p_title, &ui_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        if(strncasecmp(p_st_private->p_title, "topic", 5) == 0)
            p_st_private->is_topic = 1;
        else
            p_st_private->is_topic = 0;

        i_tmp_len -= ui_skip_len;
        if(i_tmp_len < 0)
            return FR_FAIL;

//        //method 上报
//        if(p_st_private->is_topic == 0)
//        {
//            if(p_st_private->i_use_request)
//                i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.method", "PUT");
//            else
//                i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.method", "GET");
//        }
//        if(i_ret == FR_FAIL)
//            return FR_FAIL;
//
//        //pub notify 通道上报
//        if(p_st_private->is_topic)
//        {
//            if(p_st_private->i_use_request)
//                i_ret = frreport_body_l7_add_str(p_st_body_data, "publish.mq.queue", p_st_private->p_title);
//            else
//                i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.queue", p_st_private->p_title);
//        }
//        if(i_ret == FR_FAIL)
//            return FR_FAIL;

        //subject   reply-to  correlation-id
        for(i_index = 0; i_index < 3; i_index++)
        {
            i_ret = amqp_skip_content(p_st_data, &ui_skip_len);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_tmp_len -= ui_skip_len;
            if(i_tmp_len < 0)
                return FR_FAIL;
        }

        // content_type
        i_ret = amqp_get_symbol(p_st_data, &p_st_private->p_content_type, &ui_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_tmp_len -= ui_skip_len;
        if(i_tmp_len < 0)
            return FR_FAIL;

        // content_encoding
        i_ret = amqp_get_symbol(p_st_data, &p_st_private->p_content_encoding, &ui_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_tmp_len -= ui_skip_len;
        if(i_tmp_len < 0)
            return FR_FAIL;

        //跳过该链表剩余项
        i_ret = bytebuff_skip(p_st_data, i_tmp_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

    }

    return FR_SUCC;

}


/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_mess_content(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, st_amqp_private_data *p_st_private)
{
    int i_ret = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    if(p_st_private->i_use_request)
    {
        i_ret = amqp_get_content(p_st_data, p_st_body_data, NULL, p_st_private->i_use_request);
    }
    else
    {
        i_ret = amqp_get_content(p_st_data, p_st_body_data, NULL, p_st_private->i_use_request);
    }


    return i_ret;

}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_add_disposition(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, st_amqp_private_data *p_st_private)
{
    int i_ret = 0;
    char c_type;
    int i_tmp_len = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //mess header  list
    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;
    if(c_type == '\xc0')
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\xd0')
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\x45')
    {
        i_tmp_len = 0;
    }
    else
    {
        return FR_FAIL;
    }

    if(i_tmp_len)
    {
        i_ret = bytebuff_skip(p_st_data, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_tmp_len--;
        if(i_tmp_len < 0)
            return FR_FAIL;

//        if(c_type == '\x41')
//            p_st_private->is_producer = 0;
//        else if(c_type == '\x42')
//            p_st_private->is_producer = 1;
//        else
//            return FR_FAIL;

        i_ret = bytebuff_skip(p_st_data, i_tmp_len);
        return i_ret;

    }

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_get_username(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, L7session_amqp_private *p_st_session_private)
{
    char *p_field_tmp = NULL;
    int i_ret = 0;
    char c_type;
    int i_tmp_len = 0, ui_skip_len = 0;
    char *p_mechanism = NULL;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_session_private == NULL)
        return FR_FAIL;

    //arguments  list
    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(c_type == '\xc0')
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\xd0')
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\x45')
    {
        i_tmp_len = 0;
    }
    else
    {
        return FR_FAIL;
    }

    if(i_tmp_len)
    {
        i_ret = bytebuff_skip(p_st_data, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        //mechanism
        i_ret = amqp_get_symbol(p_st_data, &p_mechanism, &ui_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        //Init-response  0x00 user 0x00 password
        i_ret = amqp_get_binary(p_st_data, &p_field_tmp, &ui_skip_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_mechanism);
            return FR_FAIL;
        }

        if(strcmp(p_mechanism, "PLAIN") == 0)
        {
            p_st_session_private->p_user_name = frstrdup(p_field_tmp + 1);
            if(p_st_session_private->p_user_name == NULL)
            {
                frfree(p_field_tmp);
                frfree(p_mechanism);
                return FR_FAIL;
            }
        }
        else
        {
            //todo
        }

    }
    if(p_field_tmp)
        frfree(p_field_tmp);
    if(p_mechanism)
        frfree(p_mechanism);

    return FR_SUCC;

}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_get_responsecode(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, st_amqp_private_data *p_st_private, int *p_i_datatype)
{
    int i_ret = 0;
    unsigned char uc_code = 0;
    int i_tmp_len = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL || p_i_datatype == NULL)
        return FR_FAIL;

    //arguments  list
    i_ret = bytebuff_get_char(p_st_data, &uc_code);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(uc_code == 0xc0)
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(uc_code == 0xd0)
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(uc_code == 0x45)
    {
        i_tmp_len = 0;
    }
    else
    {
        return FR_FAIL;
    }

    if(i_tmp_len)
    {
        i_ret = bytebuff_skip(p_st_data, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        i_ret = bytebuff_get_char(p_st_data, &uc_code);
        if(i_ret == FR_FAIL || uc_code != 0x50)
            return FR_FAIL;

        i_ret = bytebuff_get_char(p_st_data, &uc_code);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        switch (uc_code)
        {
            //code
            case 0x00:
                *p_i_datatype = FRLOGIN_SUCC;
                break;

            default:
                *p_i_datatype = FRLOGIN_FAIL;
                return FR_FAIL;
        }
    }

    return FR_SUCC;
}


int amqp_skip_long(Frbyte_Packet *p_st_data, int *p_i_skip_len)
{
    int i_ret =0;
    char c_type;

    if(p_st_data == NULL || p_i_skip_len == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(c_type)
    {
        case '\x44':
            *p_i_skip_len = 1;
            break;

        case '\x53':
            i_ret = bytebuff_skip(p_st_data, 1);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_i_skip_len = 2;
            break;

        case '\x80':
            i_ret = bytebuff_skip(p_st_data, 8);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            *p_i_skip_len = 9;
            break;

        default:
            return FR_FAIL;

    }

    return FR_SUCC;
}


int amqp_get_long(Frbyte_Packet *p_st_data, long long *p_ll_value)
{
    int i_ret =0;
    char c_type;
    long long ll_value = 0;

    if(p_st_data == NULL || p_ll_value == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(c_type)
    {
        case '\x44':
            ll_value = 0;
            break;

        case '\x53':
            i_ret = bytebuff_get_long(p_st_data, 1, (uint64_t *)&ll_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            break;

        case '\x80':
            i_ret = bytebuff_get_long(p_st_data, 8, (uint64_t *)&ll_value, BYTE_BIG_ENDIAN);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
            break;

        default:
            return FR_FAIL;

    }

    *p_ll_value = ll_value;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  判断是否是amqp
*  ARGS     :  p_st_data                    输入数据信息
*           :  p_st_body_data                 输入数据
*           :  p_st_private                 输入数据
*  RTN      :  APM_L7_IS_NO                 不是activeMQ数据
*           :  APM_L7_IS_YES                是activeMQ数据
*  NOTE     :
*******************************************************************************/
int amqp_get_disposition_id(Frbyte_Packet *p_st_data, int *p_i_first_id, int *p_i_last_id)
{
    int i_ret = 0;
    char c_type;
    int i_tmp_len = 0;
    int i_id_first = 0;
    int i_id_last = 0;
    int i_skip_len = 0;

    if(p_st_data == NULL || p_i_first_id == NULL || p_i_last_id == NULL)
        return FR_FAIL;

    i_ret = bytebuff_skip(p_st_data, 9);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = amqp_skip_long(p_st_data, &i_skip_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //arguments  list
    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&c_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(c_type == '\xc0')
    {
        i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\xd0')
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_tmp_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else if(c_type == '\x45')
    {
        i_tmp_len = 0;
    }
    else
    {
        return FR_FAIL;
    }

    if(i_tmp_len)
    {
        i_ret = bytebuff_skip(p_st_data, 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        //role
        i_ret = amqp_skip_content(p_st_data, &i_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        i_ret = amqp_get_int(p_st_data, &i_id_first, &i_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;

        i_ret = amqp_get_int(p_st_data, &i_id_last, &i_skip_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
        i_tmp_len--;
    }

    *p_i_first_id = i_id_first;
    *p_i_last_id = i_id_last;
    return FR_SUCC;
}

int amqp_map_message_parse(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, int i_count, int i_use_request)
{
    int i_ret = FR_SUCC;
    char *p_field_name = NULL;
    int i_skip_len = 0;
    char arr_map[256];

    if(p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    if(i_use_request)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.method", "PUT");
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_ret = frreport_body_l7_add_str(p_st_body_data, "request.mq.message.type", "hashmap");
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        i_ret = frreport_body_l7_add_int(p_st_body_data, "notify.mq.message.size", 1);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        i_ret = frreport_body_l7_add_str(p_st_body_data, "notify.mq.message.type.1", "hashmap");
        if(i_ret == FR_FAIL)
            return FR_FAIL;


    }

    while (i_count)
    {
        i_ret = amqp_get_string(p_st_data, &p_field_name, &i_skip_len);
        if(i_ret == FR_FAIL)
            return FR_SUCC;
        i_count --;

        if(i_use_request)
        {
            snprintf(arr_map, sizeof(arr_map), "request.mq.map.%s",p_field_name);
        }
        else
        {
            snprintf(arr_map, sizeof(arr_map), "notify.mq.map.1.%s",p_field_name);
        }

        frfree(p_field_name);

        i_ret = amqp_get_content(p_st_data, p_st_body_data, arr_map, i_use_request);
        if(i_ret == FR_FAIL)
            return FR_SUCC;
        i_count --;
    }

    return FR_SUCC;
}


